/*
MIT License

Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,

https://bmstu.codes/lsx/simodo
*/

#include "simodo/inout/convert/functions.h"

namespace simodo::inout
{

void replaceAll(std::u16string &str, const std::u16string &from, const std::u16string &to)
{
    if(from.empty())
        return;

    size_t start_pos = 0;
    while((start_pos = str.find(from, start_pos)) != std::string::npos)
    {
        str.replace(start_pos, from.length(), to);
        start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
    }
}

std::u16string replace(const std::u16string &str, const std::u16string &from, const std::u16string &to)
{
    if(from.empty())
        return str;

    std::u16string res;
    res.reserve(str.size() * 2);

    size_t start_pos = 0;
    size_t pos = 0;
    while((pos = str.find(from, start_pos)) != std::string::npos)
    {
        size_t target_pos = res.size();
        res.resize(res.size()+pos-start_pos+to.size());
        str.copy(res.data()+target_pos,pos-start_pos,start_pos);
        to.copy(res.data()+target_pos+pos-start_pos,to.size());
        start_pos = pos + from.length();
    }
    size_t target_pos = res.size();
    res.resize(res.size()+str.size()-start_pos);
    str.copy(res.data()+target_pos,str.size()-start_pos,start_pos);

    return res;
}

std::u16string encodeSpecialChars(const std::u16string & text)
{
    return replace(replace(text, u"\n", u"&NewLine;"), u"\"", u"&QUOT;");
}

std::u16string decodeSpecialChars(const std::u16string & text)
{
    return replace(replace(text, u"&NewLine;", u"\n"), u"&QUOT;", u"\"");
}

void replaceAll(std::string &str, const std::string &from, const std::string &to)
{
    if(from.empty())
        return;

    size_t start_pos = 0;
    while((start_pos = str.find(from, start_pos)) != std::string::npos)
    {
        str.replace(start_pos, from.length(), to);
        start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
    }
}

std::string encodeSpecialChars(const std::string & text)
{
    std::string res = text;
    replaceAll(res, "\n", "&NewLine;");
    replaceAll(res, "\"", "&QUOT;");
    return res;
}

std::string decodeSpecialChars(const std::string & text)
{
    std::string res = text;
    replaceAll(res, "&QUOT;", "\"");
    replaceAll(res, "&NewLine;", "\n");
    return res;
}

}
